import logging
import random
import re
import traceback
from datetime import datetime

from flask import request, abort, make_response, current_app, jsonify, session
from info import redis_store, db
from info import constants
from info.constants import SMS_CODE_REDIS_EXPIRES
from info.models import User
from info.modules.passport import passport_blue
from info.utils.captcha.captcha import captcha
from info.utils.response_code import RET, error_map


@passport_blue.route("/image_code")
def get_img_code():
    # 1、获取参数
    code_id = request.args.get("code_id")
    if not code_id:
        logging.error("未传入code_id")
        abort(404)
    # 2、生成验证码
    name, text, image = captcha.generate_captcha()
    print("验证码名字", name)
    print("验证码text", text)
    print("验证码image", image)
    try:
        # 保存当前生成的图片验证码内容
        redis_store.setex(code_id, constants.IMAGE_CODE_REDIS_EXPIRES, text)
    except Exception as e:
        logging.error(e)
        abort(500)
    # 5、响应返回
    response = make_response(image)
    response.headers['Content-Type'] = 'image/jpg'
    return response


@passport_blue.route("/smscode", methods=["POST"])
def sms_code():
    print("进入了获取验证码的函数")
    data = request.json
    print("获取到的get", data)
    # 1、获取数据
    mobile = data.get("mobile")
    image_code = data.get("image_code")
    image_code_id = data.get("image_code_id")
    print("获取到的数据", mobile, image_code, image_code_id)
    # 2、校验传入的数据是否都存在
    if not all([mobile, image_code, image_code_id]):
        ret = {
            "errno": RET.NODATA,
            "errmsg": error_map[RET.NODATA]
        }
        return jsonify(ret)
    print("通过数据存在验证")
    # 3、校验输入的手机号是否正确
    if not re.match(r"^1[35789][0-9]{9}$", mobile):
        ret = {
            "errno": RET.DATAERR,
            "errmsg": "手机号输入错误"
        }
        return jsonify(ret)
    print("手机号正确")
    # 4、校验传入的图片验证码是否正确
    # 从数据库将验证码查询出来
    real_iamge_code = None
    try:
        name = redis_store.get(image_code_id)
        print("数据库提取的验证码", name)
        if name:
            real_iamge_code = name.decode()
            redis_store.delete(image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        ret = {
            "errno": RET.DBERR,
            "errmsg": error_map[RET.DBERR]
        }
        return jsonify(ret)

    # 判断验证码是否过期
    if not real_iamge_code:
        ret = {
            "errno": RET.DBERR,
            "errmsg": "当前验证码已过期"
        }
        return jsonify(ret)

    if image_code.lower() != real_iamge_code.lower():
        ret = {
            "errno": RET.DATAERR,
            "errmsg": "验证码输入错误"
        }
        return jsonify(ret)
    print("验证码校验通过")
    # 校验手机是否已经注册
    try:
        mobile_data = db.session.query(User).filter_by(mobile=mobile).first()
        print("sql数据库查询出来的数据", mobile_data)
    except Exception as e:
        current_app.logger.error("校验手机号是否已经注册数据库查询失败")
        print(e)
    if mobile_data:
        ret = {
            "errno": RET.DATAERR,
            "errmsg": "该手机号已经存在"
        }
        print("该手机号已经存在")
        return jsonify(ret)
    print("数据库手机号不存在")
    result = random.randint(1, 999999)
    datas = ["%06d" % result, SMS_CODE_REDIS_EXPIRES]
    datas_two = datas[0]
    print("生成随机码", datas)
    # 发送短信
    # num = send_message(mobile=mobile, datas=datas)
    # if num != "0":
    #     ret = {
    #         "errno": RET.DATAERR,
    #         "errmsg": "短信发送失败"
    #     }
    #     print("短信发送失败")
    #     return jsonify(ret)
    # print("成功发送信息")
    try:
        redis_store.setex("SMS_" + mobile, SMS_CODE_REDIS_EXPIRES, datas_two)
    except Exception as e:
        current_app.logger.error(e)
        ret = {
            "errno": RET.DATAERR,
            "errmsg": "redis储存失败,请稍后再试"
        }
        return jsonify(ret)
    print("返回ok")
    return jsonify(errno=RET.OK, errmsg="发送成功")


@passport_blue.route("/register", methods=["POST"])
def register():
    json_data = request.json
    mobile = json_data.get("mobile")
    smscode = json_data.get("smscode")
    password = json_data.get("password")
    # 1、校验传入进来的数据是否都存在
    if not all([mobile, smscode, password]):
        ret = {
            "errno": RET.NODATA,
            "errmsg": "参数不能为空"
        }
        return jsonify(ret)
    # 2、校验验证码输入的是否正确
    try:
        sms_mobile = redis_store.get("SMS_" + mobile)
    except Exception as e:
        current_app.logger.error(e)
        traceback.print_exc()
        ret = {
            "errno": RET.DBERR,
            "errmsg": "数据库查询失败"
        }
        return jsonify(ret)
    if not sms_mobile:
        return jsonify(errno=RET.DATAERR, errmsg="验证码已超出有效期")

    sms = sms_mobile.decode()
    redis_store.delete(sms_mobile)

    if smscode != sms:
        ret = {
            "errno": RET.DBERR,
            "errmsg": "手机验证码输入错误"
        }
        return jsonify(ret)

    # 将用户保存到sql数据库
    user = User()
    user.nick_name = mobile
    user.password = password
    user.mobile = mobile
    user.last_login = datetime.now()

    # 提交数据
    try:
        db.session.add(user)
        db.session.commit()

    except Exception as e:
        current_app.logger.error(e)
        ret = {
            "errno": RET.DBERR,
            "errmsg": "注册失败,请稍后再试"
        }
        return jsonify(ret)

    # 保存用户登录状态
    session['user_id'] = user.id
    session['mobile'] = user.mobile
    session['nick_name'] = user.nick_name
    # 关闭数据库
    db.session.close()
    # 返回相应数据
    return jsonify(errno=RET.OK, errmsg='注册成功')


@passport_blue.route("/login", methods=["POST"])
def login():
    re_json = request.json
    mobile = re_json.get("mobile")
    password = re_json.get("password")

    # 判断上传的数据是否为空
    if not all([mobile, password]):
        return jsonify(errno=RET.DATAERR, errmsg="参数不能为空哦")

    # 校验传入的手机号是否存在
    if not re.match('1[35678]\\d{9}', mobile):
        return jsonify(errno=RET.PARAMERR, errmsg="手机号格式不正确")

    # 校验用户是否存在
    try:
        user = User.query.filter(User.mobile == mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据查询错误")

    if not user:
        return jsonify(errno=RET.DATAERR, errmsg="用户不存在")

    # 校验密码是否正确
    if not user.check_password(password):
        return jsonify(errno=RET.DATAERR, errmsg="账号或密码错误")

    # 设置登录状态
    session["user_id"] = user.id
    session["mobile"] = user.mobile
    session["nick_name"] = user.nick_name

    # 设置当前用户最后一次登录时间
    user.last_login = datetime.now()

    return jsonify(errno=RET.OK, errmsg="登录成功")


@passport_blue.route("/logout", methods=["POST"])
def logout():
    print("进入退出函数")
    # 删除coock值
    session.pop("user_id")
    session.pop("mobile")
    session.pop("nick_name")

    return jsonify(errno=RET.OK, errmsg="OK")
